#include "rclcpp/rclcpp.hpp"
#include <cpp-httplib/httplib.h>
#include <functional>
#include <iostream>
#include <string>
#include <thread>
#include <vector>

class NovalDownload : public rclcpp::Node
{
private:
    std::vector<std::thread *> tv;

public:
    NovalDownload(const std::string &node_name) : rclcpp::Node(node_name) {}
    ~NovalDownload() {}
    void
    download(const std::string &host, const std::string &path,
             std::function<void(const std::string &, const std::string &)> cb)
    {
        std::cout << "this thread: " << std::this_thread::get_id()
                  << ", try download: " << host << "/" << path << std::endl;
        httplib::Client client(host);
        auto response = client.Get(path);
        if (response && response->status == 200)
        {
            cb(path, response->body);
        }
    }
    void start(const std::string &host, const std::string &path,
               std::function<void(const std::string &, const std::string &)> cb)
    {
        auto download_func =
            std::bind(&NovalDownload::download, this, std::placeholders::_1,
                      std::placeholders::_2, std::placeholders::_3);
        std::thread *thd = new std::thread(download_func, host, path, cb);
        tv.push_back(thd);
    }
    void run()
    {
        auto call_back = [this](const std::string &path,
                            const std::string &result) -> void
        {
            RCLCPP_INFO(this->get_logger(),
                        "ffinish:%s, len:%d, concept:%s ...", path,
                        result.length(), result.substr(0, 18));
        };
        start("http://localhost:8000", "/other/noval1.txt", call_back);
        start("http://localhost:8000", "/other/noval2.txt", call_back);
        start("http://localhost:8000", "/other/noval3.txt", call_back);

        std::this_thread::sleep_for(std::chrono::milliseconds(10 * 000));
        for (long unsigned int i = 0; i < tv.size() - 1; i++)
        {
            if (tv[i]->joinable())
            {
                tv[i]->join();
            }
            delete tv[i];
        }
    }
};

int main(int argc, char **argv)
{
    rclcpp::init(argc, argv);
    auto node = std::make_shared<NovalDownload>("noval");
    node->run();
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}